<route>
  {
    style: {
      navigationBarTitleText: '智能问答',
    }
  }
</route>

<script lang="ts" setup>
import { ref, nextTick } from 'vue'
import { getMessageAPI, getChatAPI } from '@/api/knowChat'
import { chatParams, MessageResult } from '@/types/knowChat'
import ChatPopup from './components/ChatPopup.vue'
import { ChatPopupInstance } from '@/types/components-instance'

// 状态变量
const currentChatId = ref('') // 当前选中的聊天ID
const messages = ref<MessageResult[]>([]) // 当前聊天的消息列表
const inputMessage = ref('') // 输入框内容
const loading = ref(false) // 加载状态
const scrollTop = ref(0) // 滚动位置

const chatSocketTask = ref<UniApp.SocketTask>()

// 弹窗展示
const show = ref(false)

// 获取消息列表
const getChatDetailData = async (chatId: string) => {
  show.value = false
  console.log(chatId)
  changeChatId(chatId)
  const res = await getMessageAPI(chatId)
  messages.value = res.data
}

// 获取对话历史的组件实例
const chatPopupRef = ref<ChatPopupInstance>()

// 初始化
onLoad(async () => {
  // 创建新的聊天
  createNewChat()
})

// 创建新聊天
const createNewChat = () => {
  show.value = false
  const newChatId = new Date().getTime().toString(36) + Math.random().toString(36).substr(2)
  changeChatId(newChatId)
  // 清空消息列表
  messages.value = []
}

// 切换聊天ID
const changeChatId = async (chatId: string) => {
  currentChatId.value = chatId
  // 初始化WebSocket连接
  chatSocketTask.value?.close({
    success: () => {
      console.log('chatWebSocket连接已关闭')
    },
  })
  chatSocketTask.value = await uni.connectSocket({
    url: import.meta.env.VITE_APP_WS_BASEURL + '/member/ws/know/' + chatId,
    complete: (res) => {
      console.log('WebSocket连接已打开', res)
    },
  })
}

// 发送消息函数修改
const sendMessage = async () => {
  if (!inputMessage.value.trim() || loading.value) return
  // 添加用户消息到列表
  const userMessage: MessageResult = {
    role: 'user',
    content: inputMessage.value.trim(),
  }
  messages.value.push(userMessage)
  // 清空输入框
  const tempMessage = inputMessage.value
  inputMessage.value = ''

  // 滚动到底部
  scrollToBottom()
  // 添加AI消息占位
  const aiMessage: MessageResult = {
    role: 'assistant',
    content: '',
  }
  messages.value.push(aiMessage)
  // 设置加载状态
  loading.value = true
  // 调用API发送消息
  const params: chatParams = {
    prompt: tempMessage,
    chatId: currentChatId.value,
  }

  // 发送消息请求
  await getChatAPI(params)
  // 获取AI返回的消息
  getAIMessage(aiMessage)
}

// AI消息返回
const getAIMessage = async (aiMessage: MessageResult) => {
  let accumulatedContent = '' // 用于缓存未完成的消息
  await chatSocketTask.value.onMessage(async (res) => {
    console.log('收到服务器消息：', res.data)
    const data = res.data
    // 如果是逐帧发送的文本数据
    if (typeof data === 'string') {
      if (data === '[END]') {
        // textToSpeech(accumulatedContent)
        loading.value = false
        return
      }
      accumulatedContent += data
      await nextTick(() => {
        const updatedMessage = {
          ...aiMessage,
          content: accumulatedContent, // 使用累积的内容
        }
        const lastIndex = messages.value.length - 1
        messages.value.splice(lastIndex, 1, updatedMessage)
        nextTick(() => {
          scrollToBottom()
          console.log('滚动到底部')
        })
      })
    }
  })
}

// 滚动到底部
const toView = ref('s0')
const scrollToBottom = () => {
  toView.value = 's' + messages.value.length
}

// 切换历史面板
const toggleHistory = () => {
  show.value = true
  chatPopupRef.value?.getHistoryListData()
}

// 组件卸载时关闭WebSocket连接
onUnload(() => {
  chatSocketTask.value?.close({
    success: () => {
      console.log('WebSocket连接已关闭')
    },
  })
})
</script>

<template>
  <view class="chat-container">
    <!-- 添加 ChatPopup 组件 -->
    <wd-popup v-model="show" position="left" custom-style="width: 95vw;background-color: #FEFEFE;">
      <ChatPopup
        class="h-full flex flex-col"
        @toChatDetail="getChatDetailData"
        @createSession="createNewChat"
        ref="chatPopupRef"
      />
    </wd-popup>
    <!-- 主聊天区域 -->
    <view class="chat-main">
      <!-- 聊天头部 -->
      <view class="chat-header">
        <view class="header-left" @click="toggleHistory">
          <i class="iconfont icon-caidan"></i>
        </view>
        <view class="header-title">
          {{ '智能问答' }}
        </view>
        <view class="header-right" @click="createNewChat">
          <i class="iconfont icon-add"></i>
        </view>
      </view>

      <!-- 消息列表 -->
      <scroll-view
        scroll-y
        class="message-list"
        :scroll-top="scrollTop"
        :scroll-with-animation="true"
        :scroll-into-view="toView"
      >
        <view class="message-list-inner">
          <!-- 欢迎消息 -->
          <view class="welcome-message" v-if="messages.length === 0">
            <view class="welcome-title">欢迎使用智能问答</view>
            <view class="welcome-desc">您可以向我提问任何问题，我会尽力回答</view>
          </view>

          <!-- 消息项 -->
          <view
            v-for="(msg, idx) in messages"
            :id="'s' + idx"
            :key="idx"
            class="message-item"
            :class="{ 'message-user': msg.role === 'user', 'message-ai': msg.role === 'assistant' }"
          >
            <view class="message-avatar">
              <image
                :src="
                  msg.role === 'user'
                    ? '/static/images/user-avatar.png'
                    : '/static/images/ai-avatar.png'
                "
                mode="aspectFit"
              ></image>
            </view>
            <view class="message-content">
              <text>{{ msg.content }}</text>
            </view>
          </view>

          <!-- 加载中状态 -->
          <view class="loading-message" v-if="loading">
            <view class="loading-dots">
              <view class="dot"></view>
              <view class="dot"></view>
              <view class="dot"></view>
            </view>
          </view>
        </view>
      </scroll-view>

      <!-- 输入区域 -->
      <view class="input-area">
        <textarea
          v-model="inputMessage"
          class="message-input"
          placeholder="输入消息..."
          placeholder-style="color: #9C94FE; font-size: 28rpx"
          :auto-height="true"
          :cursor-spacing="20"
          :show-confirm-bar="false"
          confirm-type="send"
          @confirm="sendMessage"
        />
        <view
          class="send-btn"
          :class="{ 'send-btn-disabled': !inputMessage.trim() || loading }"
          @click="sendMessage"
        >
          <!-- <text class="send-icon">></text> -->
          <i class="iconfont icon-send" style="font-size: 45rpx"></i>
        </view>
      </view>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.chat-container {
  // display: flex;
  height: 100%; /* 减去底部tabBar的高度 */
  background-color: #f5f7fa;
  position: relative;
  .chat-main {
    height: 100%;
  }
}

/* 历史会话侧边栏 */
.history-sidebar {
  width: 500rpx;
  height: 100%;
  background-color: #fff;
  border-right: 2rpx solid #ebeef5;
  display: flex;
  flex-direction: column;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 10;
  box-shadow: 4rpx 0 16rpx rgba(0, 0, 0, 0.1);
}

.history-header {
  height: 100rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 15px;
  border-bottom: 1px solid #ebeef5;
}

.history-title {
  font-size: 16px;
  font-weight: bold;
}

.close-btn {
  padding: 5px;
}

.history-list {
  flex: 1;
  overflow-y: auto;
}

.history-item {
  padding: 15px;
  border-bottom: 1px solid #ebeef5;
  cursor: pointer;
}

.history-item.active {
  background-color: #f0f9ff;
  border-left: 3px solid #1989fa;
}

.history-item-title {
  font-size: 14px;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.history-item-time {
  font-size: 12px;
  color: #909399;
}

.history-footer {
  padding: 15px;
  border-top: 1px solid #ebeef5;
  display: flex;
  justify-content: center;
}

/* 主聊天区域 */
.chat-main {
  flex: 1;
  margin-left: 0;
  display: flex;
  flex-direction: column;
  transition: margin-left 0.3s;
}

.chat-main-full {
  margin-left: 0;
}

.chat-header {
  height: 100rpx;
  background-color: #fff;
  border-bottom: 2rpx solid #ebeef5;
  display: flex;
  align-items: center;
  padding: 0 10rpx;
}

.header-left,
.header-right {
  width: 80rpx;
  height: 80rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-title {
  flex: 1;
  text-align: center;
  font-size: 32rpx;
  font-weight: bold;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 消息列表 */
.message-list {
  flex: 1;
  // padding: 30rpx;
  box-sizing: border-box;
  overflow-y: auto;
}

.message-list-inner {
  display: flex;
  padding: 30rpx;
  flex-direction: column;
}

.welcome-message {
  text-align: center;
  padding: 30px 0;
}

.welcome-title {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 10px;
}

.welcome-desc {
  font-size: 14px;
  color: #909399;
}

.message-item {
  display: flex;
  margin-bottom: 15px;
  align-items: flex-start;
}

.message-user {
  flex-direction: row-reverse;
}

.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  margin: 0 10px;
}

.message-avatar image {
  width: 100%;
  height: 100%;
}

.message-content {
  max-width: 70%;
  padding: 10px 15px;
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.5;
  word-break: break-word;
}

.message-user .message-content {
  background-color: #584cf4;
  color: #fff;
  border-top-right-radius: 0;
  border-bottom-left-radius: 20px; /* 左下角圆角 */
  border-bottom-right-radius: 20px; /* 右下角圆角 */
  border-top-left-radius: 20px; /* 左上角圆角 */
  padding: 10px 20px; /* 内边距 */
  display: inline-block; /* 让元素可以内联显示 */
  font-size: 16px; /* 文字大小 */
  line-height: 1.5; /* 行高 */
}

.message-ai .message-content {
  background-color: #fff;
  color: #333;
  border-top-left-radius: 0; /* 左上角无圆角 */
  border-bottom-left-radius: 20px; /* 左下角圆角 */
  border-bottom-right-radius: 20px; /* 右下角圆角 */
  border-top-right-radius: 20px; /* 右上角圆角 */
  padding: 10px 20px; /* 内边距 */
  display: inline-block; /* 让元素可以内联显示 */
  font-size: 16px; /* 文字大小 */
  line-height: 1.5; /* 行高 */
}

.loading-message {
  display: flex;
  justify-content: center;
  margin: 10px 0;
}

.loading-dots {
  display: flex;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #1989fa;
  margin: 0 3px;
  animation: dot-flashing 1s infinite alternate;
}

.dot:nth-child(2) {
  animation-delay: 0.2s;
}

.dot:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes dot-flashing {
  0% {
    opacity: 0.2;
  }
  100% {
    opacity: 1;
  }
}

/* 输入区域 */
.input-area {
  padding: 16rpx 24rpx;
  background-color: #fff;
  border-top: 2rpx solid #ebeef5;
  display: flex;
  align-items: center;
  gap: 20rpx;
}

.message-input {
  flex: 1;
  min-height: 80rpx;
  max-height: 240rpx;
  background-color: #f5f5f5;
  border-radius: 40rpx;
  padding: 16rpx 30rpx;
  font-size: 28rpx;
  line-height: 24rpx;
  caret-color: #4333fe; /* 设置光标颜色为橙色 */
}

.send-btn {
  width: 90rpx;
  height: 90rpx;
  border-radius: 50%;
  background-color: #4433ff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 0;
}

.send-btn-disabled {
  background-color: #c1befe;
}

.send-icon {
  color: #fff;
  font-size: 32rpx;
  font-weight: bold;
  line-height: 1;
}
</style>
